package com.wangsd.web.mqpay.service;

import com.alibaba.fastjson.JSON;
import com.gitee.fastmybatis.core.query.Query;
import com.gitee.fastmybatis.core.query.Sort;
import com.wangsd.common.utils.HttpClientUtils;
import com.wangsd.common.utils.MD5Utils;
import com.wangsd.web.mqpay.entity.Customer;
import com.wangsd.web.mqpay.entity.Trade;
import com.wangsd.web.mqpay.mapper.TradeMapper;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

@Service
public class TradeService {
    @Resource
    private TradeMapper mapper;
    @Autowired
    private CustomerService customerService;

    private Query getQuery(Trade queryObj, String code) {
        Query query = new Query();
        if (StringUtils.isNotBlank(queryObj.getOutTradeNo())) {
            query.like("out_trade_no", queryObj.getOutTradeNo());
        }
        if (StringUtils.isNotBlank(code)) {
            query.likeRight("code", code);
        }
        if (StringUtils.isNotBlank(queryObj.getCode())) {
            query.likeRight("code", queryObj.getCode());
        }
        if (queryObj.getParentCode() != null) {
            query.eq("parent_code", queryObj.getParentCode());
        }
        if (queryObj.getPayCode() != null) {
            query.eq("pay_code", queryObj.getPayCode());
        }
        if (queryObj.getStatus() != null) {
            query.eq("status", queryObj.getStatus());
        }
        if (queryObj.getNotifyStatus() != null) {
            query.eq("notify_status", queryObj.getNotifyStatus());
        }
        if (queryObj.getNotifyStatus() != null) {
            query.eq("notify_status", queryObj.getNotifyStatus());
        }
        if (StringUtils.isNotBlank(queryObj.getBeginTime())) {
            query.ge("created_time", queryObj.getBeginTime());
        }
        if (StringUtils.isNotBlank(queryObj.getEndTime())) {
            query.le("created_time", queryObj.getEndTime());
        }
        return query;
    }

    public List<Trade> selectPage(Trade queryObj, String code) {
        Query query = this.getQuery(queryObj, code);
        query.orderby("created_time", Sort.DESC);
        List<Trade> list = mapper.list(query);
        return list;
    }

    /**
     * 根据条件统计
     * @param queryObj
     * @param code
     * @return
     */
    public Map selectStatistics(Trade queryObj, String code) {
        Query query = this.getQuery(queryObj, code);
        List<String> column = Arrays.asList("count( 1 ) AS orderCount,\n" +
                "\tSUM( amount ) * 0.01 AS orderAmount,\n" +
                "\tSUM( CASE WHEN status = 1 THEN 1 ELSE 0 END ) AS payCount,\n" +
                "\tSUM( CASE WHEN status = 1 THEN amount ELSE 0 END ) * 0.01 AS payAmount,\n" +
                "\tSUM( CASE WHEN status = 0 OR status = 2 THEN 1 ELSE 0 END ) AS unpayCount,\n" +
                "\tSUM( CASE WHEN status = 0 OR status = 2 THEN amount ELSE 0 END ) * 0.01 AS unpayAmount");
        List<Map<String, Object>> mapList = mapper.listMap(column, query);
        Map<String, Object> map = new HashMap<>();
        if (mapList != null && mapList.size() > 0) {
            map = mapList.get(0);
        }
        return map;
    }

    public int save(Map<String, String> map) {
        Trade trade = new Trade();
        trade.setAmount(Integer.parseInt(map.get("amount")));
        Customer customer = customerService.selectByCustomerNo(map.get("customerNo"));
        trade.setCode(customer.getCode());
        trade.setParentCode(customer.getCode());
        trade.setCustomerName(customer.getName());
        trade.setNotifyStatus(0);
        trade.setNotifyUrl(map.get("notifyUrl"));
        trade.setOutTradeNo(map.get("outTradeNo"));
        trade.setPayCode(map.get("payCode"));
        trade.setStatus(0);
        trade.setPassagewayName(map.get("passagewayName"));
        trade.setMerchantId(map.get("merchantId") != null ? Long.parseLong(map.get("merchantId")) : null);
        trade.setMerchantName(map.get("merchantName"));
        return mapper.saveIgnoreNull(trade);
    }

    public Trade selectByOutTradeNo(String outTradeNo) {
        return mapper.getByQuery(new Query().eq("out_trade_no", outTradeNo));
    }

    /**
     * 回调通知
     *
     * @param trade
     * @param transactionId
     * @return
     */
    public boolean doNotice(Trade trade, String transactionId) {
        boolean isFlag = false;
        if (trade.getNotifyStatus() != 1) { //未通知成功
            SortedMap<String, String> map = new TreeMap();
            map.put("outTradeNo", trade.getOutTradeNo());
            map.put("transactionId", transactionId);
            map.put("amount", trade.getAmount() + "");
            map.put("payCode", trade.getPayCode());
            map.put("status", "1");
            Customer customer = customerService.selectByCode(trade.getParentCode());
            map.put("sign", MD5Utils.getMD5Sign(map, customer.getApiKey(), 1));

            String result = HttpClientUtils.post(trade.getNotifyUrl(), JSON.toJSONString(map), "UTF-8");
            if ("success".equalsIgnoreCase(result)) {
                trade.setStatus(1);
                trade.setNotifyStatus(1);
                isFlag = true;
            } else {
                trade.setStatus(1);
                trade.setNotifyStatus(2);
            }
            if (StringUtils.isNotBlank(transactionId)) {
                trade.setTransactionId(transactionId);
            }
            mapper.updateIgnoreNull(trade);
        }
        return isFlag;
    }

}
